package com.cskaoyan.controller;

import com.cskaoyan.bean.data.HomeAboutData;
import com.cskaoyan.bean.vo.BaseRespVo;
import com.cskaoyan.model.MarketAd;
import com.cskaoyan.model.MarketBrand;
import org.apache.shiro.SecurityUtils;
import com.cskaoyan.service.*;


import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.concurrent.*;

/**
 * @Author Pudding
 * @Date 2024/6/10 12:53
 */
@RequestMapping("wx/home")
@RestController
public class WxHomeController {
    @Autowired
    AdService adService; // bannerService
    @Autowired
    BrandService brandService;
    @Autowired
    CategoryService categoryService; // channelService
    @Autowired
    CouponService couponService;
    @Autowired
    GoodsService goodsService; // floorGoodsList、hotGoodsList、newGoodsList
    @Autowired
    TopicService topicService;
    @Autowired
    SystemService systemService;
    // 首页显示数量的限制


    // 访问/wx/home/index 可以使用线程池来做

    @GetMapping("index")
    public BaseRespVo index() throws ExecutionException, InterruptedException {
        //创建线程池对象，这个线程池开辟10条线程
        ExecutorService pool = Executors.newFixedThreadPool(10);

        Map<String, Object> dataMap = new HashMap<>(); // 存储响应报文中的data数据

        // 1. 首页轮播图
        //List<MarketAd> banners = adService.query();
        //创建带有返回值的线程任务：实现Callable接口的子类对象
        Callable<List<MarketAd>> callableAd = () -> adService.query();
        //创建FutureTask任务对象，一旦运行就执行给定的Callable
        FutureTask<List<MarketAd>> futureTaskAd = new FutureTask<>(callableAd);
        //线程池对象提交任务
        pool.submit(futureTaskAd);
        //通过FutureTask子类对象中的get()方法获取线程执行完之后的返回值
        dataMap.put("banner", futureTaskAd.get());

        // 2.首页分类(一级类目)信息
        //List channels = categoryService.queryLevelOne();
        Callable<List> callableCategory = () -> categoryService.queryLevelOne();
        FutureTask<List> futureTaskCategory = new FutureTask<>(callableCategory);
        pool.submit(futureTaskCategory);
        dataMap.put("channel", futureTaskCategory.get());

        // 3. 获取system表中的数据（key_name -- key_value数据）
        Callable<Map<String, String>> callableSystemConfig = () -> systemService.toMap();
        FutureTask<Map<String, String>> futureTaskSystemConfig = new FutureTask<>(callableSystemConfig);
        pool.submit(futureTaskSystemConfig);
        Map<String, String> systemConfig = futureTaskSystemConfig.get();

        // 3.1 品牌制造商直供栏目
        int brandLimit = Integer.parseInt(systemConfig.get("market_wx_index_brand"));
        //List<MarketBrand> brandList = brandService.list(1, brandLimit);
        Callable<List<MarketBrand>> callableBrand = () -> brandService.list(1, brandLimit);
        FutureTask<List<MarketBrand>> futureTaskBrand = new FutureTask<>(callableBrand);
        pool.submit(futureTaskBrand);
        dataMap.put("brandList", futureTaskBrand.get());

        // 3.2 商品新品首发
        int newLimit = Integer.parseInt(systemConfig.get("market_wx_index_new"));
        //List<MarketGoods> newGoodsList = goodsService.goodsList(false, true, 1, newLimit);
        Callable<List> callableNewGoods = () -> goodsService.goodsList(false, true, 1, newLimit);
        FutureTask<List> futureTaskNewGoods = new FutureTask<>(callableNewGoods);
        pool.submit(futureTaskNewGoods);
        dataMap.put("newGoodsList", futureTaskNewGoods.get());

        // 3.3 商品人气推荐
        int hotLimit = Integer.parseInt(systemConfig.get("market_wx_index_hot"));
        //List<MarketGoods> hotGoodsList = goodsService.goodsList(true, false, 1, hotLimit);
        Callable<List> callableHotGoods = () -> goodsService.goodsList(true, false, 1, hotLimit);
        FutureTask<List> futureTaskHotGoods = new FutureTask<>(callableHotGoods);
        pool.submit(futureTaskHotGoods);
        dataMap.put("hotGoodsList", futureTaskHotGoods.get());

        // 3.4 专题精选
        int topicLimit = Integer.parseInt(systemConfig.get("market_wx_index_topic"));
        //List<MarketTopic> topicList = topicService.list(1, topicLimit);
        Callable<List> callableTopic = () -> topicService.list(1, topicLimit);
        FutureTask<List> futureTaskTopic = new FutureTask<>(callableTopic);
        pool.submit(futureTaskTopic);
        dataMap.put("topicList", futureTaskTopic.get());

        long l = System.currentTimeMillis();
        // 3.5 floorGoodsList 分类栏目有限制的显示
        int categoryLimit = Integer.parseInt(systemConfig.get("market_wx_catlog_list"));
        int categoryGoodsLimit = Integer.parseInt(systemConfig.get("market_wx_catlog_goods"));
        //List floorGoodsList = goodsService.floorGoodsList(categoryLimit, categoryGoodsLimit);
        Callable<List> callableFloorGoods = () -> goodsService.floorGoodsList(categoryLimit, categoryGoodsLimit);
        FutureTask<List> futureTaskFloorGoods = new FutureTask<>(callableFloorGoods);
        pool.submit(futureTaskFloorGoods);
        dataMap.put("floorGoodsList", futureTaskFloorGoods.get());

        // 4. 优惠券，没有登录就查询所有可用优惠卷的前三个
        // 登录了就查询可用的优惠卷
        //List<Map> couponList = couponService.list(1, 3);
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {
            Callable<List> callableCoupon = () -> couponService.list(1, 3, true);
            FutureTask<List> futureTaskCoupon = new FutureTask<>(callableCoupon);
            pool.submit(futureTaskCoupon);
            dataMap.put("couponList", futureTaskCoupon.get());
        } else {
            Integer userId = (Integer) subject.getPrincipal();
            Callable<List> callableCoupon = () -> couponService.list(1, 3, false);
            FutureTask<List> futureTaskCoupon = new FutureTask<>(callableCoupon);
            pool.submit(futureTaskCoupon);
            dataMap.put("couponList", futureTaskCoupon.get());
        }
        long l1 = System.currentTimeMillis();

        System.out.println(l1 - l);

        // 最后返回响应报文即可
        return BaseRespVo.ok(dataMap);
    }

    @GetMapping("about")
    public BaseRespVo about() {
        Map<String, String> map = systemService.toMap();
        String address = map.get("market_mall_address");
        String latitude = map.get("market_mall_latitude");
        String longitude = map.get("market_mall_longitude");
        String name = map.get("market_mall_name");
        String phone = map.get("market_mall_phone");
        String qq = map.get("market_mall_qq");
        HomeAboutData data = HomeAboutData.builder()
                .address(address)
                .latitude(latitude)
                .longitude(longitude)
                .name(name)
                .phone(phone)
                .qq(qq)
                .build();
        return BaseRespVo.ok(data);
    }
}